<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>算24点</title>
  <style>
    html,
    body {
      background-color: skyblue;
      padding: 0;
      margin: 0;
    }

    .container {
      padding-top: 20px;
    }

    .card {
      position: relative;
      width: 22vw;
      height: 32vw;
      background-color: #fff;
      margin-bottom: 4vw;
      border-radius: 4px;
      font-size: 3vw;
    }

    .face {
      height: 100%;
      background-position: 50% 50%;
      background-size: 100% 100%;
    }

    .spades1 .face {
      background-image: url(./imgs/0_1.svg);
    }

    .spades2 .face {
      background-image: url(./imgs/0_2.svg);
    }

    .spades3 .face {
      background-image: url(./imgs/0_3.svg);
    }

    .spades4 .face {
      background-image: url(./imgs/0_4.svg);
    }

    .spades5 .face {
      background-image: url(./imgs/0_5.svg);
    }

    .spades6 .face {
      background-image: url(./imgs/0_6.svg);
    }

    .spades7 .face {
      background-image: url(./imgs/0_7.svg);
    }

    .spades8 .face {
      background-image: url(./imgs/0_8.svg);
    }

    .spades9 .face {
      background-image: url(./imgs/0_9.svg);
    }

    .spades10 .face {
      background-image: url(./imgs/0_10.svg);
    }

    .spades11 .face {
      background-image: url(./imgs/0_11.svg);
    }

    .spades12 .face {
      background-image: url(./imgs/0_12.svg);
    }

    .spades13 .face {
      background-image: url(./imgs/0_13.svg);
    }

    .hearts1 .face {
      background-image: url(./imgs/1_1.svg);
    }

    .hearts2 .face {
      background-image: url(./imgs/1_2.svg);
    }

    .hearts3 .face {
      background-image: url(./imgs/1_3.svg);
    }

    .hearts4 .face {
      background-image: url(./imgs/1_4.svg);
    }

    .hearts5 .face {
      background-image: url(./imgs/1_5.svg);
    }

    .hearts6 .face {
      background-image: url(./imgs/1_6.svg);
    }

    .hearts7 .face {
      background-image: url(./imgs/1_7.svg);
    }

    .hearts8 .face {
      background-image: url(./imgs/1_8.svg);
    }

    .hearts9 .face {
      background-image: url(./imgs/1_9.svg);
    }

    .hearts10 .face {
      background-image: url(./imgs/1_10.svg);
    }

    .hearts11 .face {
      background-image: url(./imgs/1_11.svg);
    }

    .hearts12 .face {
      background-image: url(./imgs/1_12.svg);
    }

    .hearts13 .face {
      background-image: url(./imgs/1_13.svg);
    }

    .clubs1 .face {
      background-image: url(./imgs/2_1.svg);
    }

    .clubs2 .face {
      background-image: url(./imgs/2_2.svg);
    }

    .clubs3 .face {
      background-image: url(./imgs/2_3.svg);
    }

    .clubs4 .face {
      background-image: url(./imgs/2_4.svg);
    }

    .clubs5 .face {
      background-image: url(./imgs/2_5.svg);
    }

    .clubs6 .face {
      background-image: url(./imgs/2_6.svg);
    }

    .clubs7 .face {
      background-image: url(./imgs/2_7.svg);
    }

    .clubs8 .face {
      background-image: url(./imgs/2_8.svg);
    }

    .clubs9 .face {
      background-image: url(./imgs/2_9.svg);
    }

    .clubs10 .face {
      background-image: url(./imgs/2_10.svg);
    }

    .clubs11 .face {
      background-image: url(./imgs/2_11.svg);
    }

    .clubs12 .face {
      background-image: url(./imgs/2_12.svg);
    }

    .clubs13 .face {
      background-image: url(./imgs/2_13.svg);
    }

    .diamonds1 .face {
      background-image: url(./imgs/3_1.svg);
    }

    .diamonds2 .face {
      background-image: url(./imgs/3_2.svg);
    }

    .diamonds3 .face {
      background-image: url(./imgs/3_3.svg);
    }

    .diamonds4 .face {
      background-image: url(./imgs/3_4.svg);
    }

    .diamonds5 .face {
      background-image: url(./imgs/3_5.svg);
    }

    .diamonds6 .face {
      background-image: url(./imgs/3_6.svg);
    }

    .diamonds7 .face {
      background-image: url(./imgs/3_7.svg);
    }

    .diamonds8 .face {
      background-image: url(./imgs/3_8.svg);
    }

    .diamonds9 .face {
      background-image: url(./imgs/3_9.svg);
    }

    .diamonds10 .face {
      background-image: url(./imgs/3_10.svg);
    }

    .diamonds11 .face {
      background-image: url(./imgs/3_11.svg);
    }

    .diamonds12 .face {
      background-image: url(./imgs/3_12.svg);
    }

    .diamonds13 .face {
      background-image: url(./imgs/3_13.svg);
    }

    .row {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-around;
    }

    .left_top {
      position: absolute;
      left: 0.6vw;
      top: 1.6vw;
    }

    .right_bottom {
      position: absolute;
      right: 0.6vw;
      bottom: 1.6vw;
    }

    .card[class^='hearts'],
    .card[class^='diamonds'] {
      color: #d40000;
    }
    .answer {
      width: 80px;
    line-height: 32px;
    border: 0;
    font-size: 14px;
    background: #e7a207;
    color: #fff;
    }
    .ans-list {
      height: calc(100vh - 200px);
      overflow: auto;
      font-size: 14px;
    line-height: 24px;
    }
  </style>
</head>

<body>
  <div class="container">
    <div class="row">
    </div>
    <div style="display: flex;justify-content: center;">
      <button class="answer" id="btn" style="margin-right: 20px;">查看答案</button>
      <button class="answer" id="next">下一题</button>
    </div>
    <div class="ans-list"></div>
  </div>
  <script src="./jquery.1.4.min.js"></script>
  <script>
    const collections = (function () {
      const result = [];
      const suits = [ 'spades', 'hearts', 'clubs', 'diamonds' ];
      const point_text = [ 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K' ];
      let i = 0;
      while (i < 52) {
        const suit = Math.floor(i / 13)
        const item = {
          suit: suits[ suit ],
          point: i % 13 + 1
        }
        item.eClass = `${ item.suit }_${ (item.point) }`
        item.point_text = point_text[ (item.point - 1) ]
        result.push(item)
        i++
      }
      return result
    }());
    let question_items = [];
    function random(min, max) {
      return Math.floor(Math.random() * (max - min)) + min;
    }

    function createACard() {
      let el
      if (collections.length) {
        const index = random(0, collections.length - 1)
        const item = (collections.splice(index, 1) || [])[ 0 ]
        question_items.push(item)
        if (item) {
          el = $(`<div class="${ item.suit + (item.point) } card">
            <div class="left_top">${ item.point_text }</div>
            <div class="face"></div>
            <div class="right_bottom">${ item.point_text }</div>
          </div>`);
          return el[ 0 ]
        }
      }
    }
    function create4Card() {
      const container = $('.row')
      if (collections.length >= 4) {
        question_items = [];
        container.append(createACard());
        container.append(createACard());
        container.append(createACard());
        container.append(createACard());
      }
    }
    create4Card();
    $('#btn').click(() => {
      const arr = question_items.map(item => item.point);
      const result = equalTo24(arr);
      $('.ans-list').html(result.join('<br/>'));
    });
    $('#next').click(() => {
      $('.row').html('');
      $('.ans-list').html('');
      create4Card();
    });

    function node(value, exp) {
       this.value = value;
       this.exp = exp;
    }
    function equalTo24(arr) {
      let answers = new Set();
      let S = new Map();
      let A = arr;
      const result = [];

      function run() {
        for (var i = 0; i < (1 << 4); i++) {
          let set = new Set();
          S.set(i, set);
        }
        for (var i = 0; i < 4; i++) {
          let n = new node(A[i], A[i] + "");
          let set = new Set();
          set.add(n);
          S.set(1 << i, set);
        }
        for (var i = 1; i < (1 << 4); i++) {
          fork(i);
        }

        let mSet = S.get((1 << 4) - 1);
        for (let v of mSet.values()) {
          if (v.value == 24) {
            answers.add(v.exp);
          }
        }
        if (answers.size == 0) {
          console.log("It's no possible");
          result.push('无解')
        }
        else {
          for (let i of answers) {
            console.log(i)
            result.push(i)
          }
        }
      }

      function fork(m) {
        var mSet = S.get(m);
        if (mSet.size > 0)
          return mSet;
        else {
          for (var x = 1; x < m; x++) {
            if ((x & m) == x) {
              let s1 = fork(x);
              let s2 = fork(m - x);
              for (let n1 of s1)
                for (let n2 of s2) {
                  var str = "(" + n1.exp + "+" + n2.exp + ")";
                  mSet.add(new node(n1.value + n2.value, str));
                  str = "(" + n1.exp + "-" + n2.exp + ")";
                  mSet.add(new node(n1.value - n2.value, str));
                  str = "(" + n2.exp + "-" + n1.exp + ")";
                  mSet.add(new node(n2.value - n1.value, str));
                  str = "(" + n1.exp + "*" + n2.exp + ")";
                  mSet.add(new node(n1.value * n2.value, str));
                  if (n1.value != 0) {
                    str = "(" + n2.exp + "/" + n1.exp + ")";
                    mSet.add(new node(n2.value / n1.value, str));
                  }
                  if (n2.value != 0) {
                    str = "(" + n1.exp + "/" + n2.exp + ")";
                    mSet.add(new node(n1.value / n2.value, str));
                  }
                }
            }
          }
          return mSet;
        }

      }
      run()
      return result
    }
  </script>
</body>
</html>
